在前幾天的文章中,我們在示範 CREATE TABLE
時,常常會看到在定義欄位時常會出現 PRIMARY KEY
, NOT NULL
那這些都是 SQL 中的約束 (Constraint)
約束用於限定 資料表
中的資料,可以保證了資料的準確性和可靠性
約束可以在創建資料表的時(CREATE TABLE)
或在資料表建立後使用 ALTER TABLE
來定義
今天就讓我們來介紹 SQL 中的約束 (Constraint) 有哪些類型,並如何通過 CREATE TABLE 或是 ALTER TABLE 來定義我們的資料表約束 (Constraint)
PRIMARY KEY
: Primary Key 稱為 主鍵
,用來約束唯一標識資料表中的每一條記錄,一個資料表只能有一個主鍵,且主鍵的值必須是唯一的,不能有重複,也不能為 NULL
範例:
CREATE TABLE users (
id SERIAL PRIMARY KEY
);
SERIAL
是 PostgreSQL 中的一種特殊的數據類型,用於自動生成的整數。這時我們將 users table 的設定顯示出來
-- 使用 \d 語法
demo_db=# \d users
Table "public.users"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+-----------------------------------
id | integer | | not null | nextval('users_id_seq'::regclass)
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
UNIQUE
: 確保在一個資料表中的所以每一列資料的某一欄位的值都是唯一的
CREATE TABLE posts (
title VARCHAR (50) UNIQUE
);
一樣使用 \d table_name
將 posts table 印出來
demo_db=# \d posts
Table "public.posts"
Column | Type | Collation | Nullable | Default
--------+-----------------------+-----------+----------+---------
title | character varying(50) | | |
Indexes:
"posts_title_key" UNIQUE CONSTRAINT, btree (title)
"posts_title_key" UNIQUE CONSTRAINT, btree (title)
我們幫 title 欄位加上了 UNIQUE CONSTRAINT
PostgreSQL 能夠快速確定一個值是否已經存在於表中,所以它使用索引來加速這個查找過程
所以這時我們來測試一下,先寫入一筆資料,再寫入相同的一筆,來看看會發生什麼事情
-- 第一次寫入
INSERT INTO posts (title) VALUES ('我是一本書') RETURNING *;
title
------------
我是一本書
(1 row)
INSERT 0 1 -- 成功的 INSERT 了
-- 第二次寫入一樣的資料
INSERT INTO posts (title) VALUES ('我是一本書') RETURNING *;
ERROR: duplicate key value violates unique constraint "posts_title_key"
DETAIL: Key (title)=(我是一本書) already exists.
我們可以看到寫入第二筆資料時,會發生錯誤因為 Key (title)=(我是一本書)
已經存在了
所以我們可以知道 unique constraint 起作用了
NOT NULL
: 確保在資料表中在設定欄位中不能有 NULL 值,即必須含有資料
CREATE TABLE members (
name varchar(60) NOT NULL
);
demo_db=# \d members
Table "public.members"
Column | Type | Collation | Nullable | Default
--------+-----------------------+-----------+----------+---------
name | character varying(60) | | not null |
這就就相對好懂一點,我們可以看到 在 members table 資訊中 Nullable
可以允許使否為 null
這邊顯示 not null 代表不能為 null
一樣來測試一下,嘗試將空的資料寫入
-- 下面兩種寫法都可以,這邊可以使用 DEFAULT VALUES 是因為我們沒有設定 name 的 DEFAULT 所以他為 null
INSERT INTO members (name) VALUES (null);
INSERT INTO members DEFAULT VALUES;
ERROR: null value in column "name" of relation "members" violates not-null constraint
DETAIL: Failing row contains (null).
DEFAULT
: 用於幫欄位設定默認值,如果寫入一筆資料,但是在設定有默認值的欄位填上值的話,則會使用默認值
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
status VARCHAR (50) DEFAULT 'Pending'
);
一樣列出 orders 資料表的資訊
demo_db=# \d orders
Table "public.orders"
Column | Type | Collation | Nullable | Default
--------+-----------------------+-----------+----------+------------------------------------
id | integer | | not null | nextval('orders_id_seq'::regclass)
status | character varying(50) | | | 'Pending'::character varying
Indexes:
"orders_pkey" PRIMARY KEY, btree (id)
我們可以看到在 Default 欄位中 status 的設定為 Pending
我們來驗證一下
INSERT INTO orders (status) VALUES ('Paid'), (DEFAULT) RETURNING *;
id | status
----+---------
1 | Paid
2 | Pending
(2 rows)
INSERT 0 2
我們可以看到我們在寫入第二筆 order 資料時,我們添入了 DEFAULT
,所以在 orders table 會呈現 Pending
今天我們介紹了什麼是 SQL 中的 Constraint,並先介紹其中的 Primary Key
Unique
Not Null
DEFAULT
明天會繼續將剩下的部分,講完,感謝大家收看